import numpy as np

# numpy： 是一个用于科学计算的工具，矩阵计算

# ndArray: 多维数组，如果是二维就代表矩阵

# 构建一个二维矩阵
nd = np.array([[1, 2, 3], [4, 5, 6]])

print(nd)
print(type(nd))
print(nd.shape)  # ndarray的形状

# 构建一个以为的向量
vertor = np.array(["1.2", "2", "3"])
print(vertor, type(vertor))

# astype： 修改ndarray中数据的类型
vertor = vertor.astype("float_")
print(vertor, type(vertor))

# ndarray索引：和列表的索引是一样的,右正下标和负下标
nd = np.array([[1, 2, 3], [4, 5, 6]])
print(nd[0])  # [1 2 3]
print(nd[0][1])  # 2
print(nd[-1])  # [4 5 6]

# 切片：切片规则和列表一致，区别在于ndarray是多维的

array = np.array([
    [1, 2, 3, 4, 5, 6],
    [2, 3, 4, 5, 6, 7],
    [3, 4, 5, 6, 7, 8],
    [4, 5, 6, 7, 8, 9],
    [5, 6, 7, 8, 9, 10],
    [6, 7, 8, 9, 10, 11]
])
# 第一个参数是对行的切片
# 第二个参数是对列的切片
# 结果位行和列的交叉
print(array[1:4, 2:5])
print(array[::2, ::2])
print(array[::, -1])

# 器对角线
# 通过下标获取元素
print(array[(0, 1, 2, 3, 4, 5), (0, 1, 2, 3, 4, 5)])
print(array[[2, 3], :3])

# 对ndarray的算术运算，实际上是在对里面的每一个元素左算术运算
print(array % 2 == 1)

# 布尔值索引
# 保留True的位置，过滤False的位置
print(array[array % 2 == 1])  # 取出所有的奇数
print(array[array > 5])  # 取出大于5的元素

# 重构,改变ndarray的形状
jishu = array[array % 2 == 1]

print(jishu.reshape((3, 6)))
print(jishu.reshape((6, 3)))

print("=" * 100)

# 拼接
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[7, 8, 9], [10, 11, 12]])
print(arr1)
print(arr2)

print(np.hstack((arr1, arr2)))  # 横向拼接
print(np.vstack((arr1, arr2)))  # 纵向拼接

# 转置
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr1)
print(arr1.T)  # 转置

# 翻转
print(np.fliplr(arr1))  # 左右翻转
print(np.flipud(arr1))  # 上下翻转
print("=" * 100)

# 矩阵相乘

arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = arr1.T

print(arr1)
print(arr2)

print(np.dot(arr1, arr2))
print("=" * 100)

# 对位运算，两个结构一样的矩阵才能左对位运算

arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[4, 5, 6], [7, 8, 9]])
print(arr1)
print(arr2)
print(arr1 + arr2)  # 对外相加
print(arr1 - arr2)  # 对位相减
print(arr1 * arr2)  # 对位乘
print(arr1 / arr2)  # 对位相除
print(arr1 // arr2)  # 整除
print(arr1 % arr2)  # 对位取余
print(arr1 ** arr2)  # 对位次方

print("=" * 100)
# 算术运算
arr1 = np.array([[1, 2, 3], [4, 5, 6]])

print(arr1 + 100)
print(arr1 - 100)
print(arr1 * 100)
print(arr1 / 100)
print(arr1 // 100)
print(arr1 % 100)
print(arr1 ** 2)

print("=" * 100)

# 数学函数
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
print(np.log2(arr1))  # 2为底的对数
print(np.log10(arr1))  # 10为底的对数
print(np.log(arr1))  # 自然对数

# 运算函数
# 差分

arr1 = np.array([1, 3, 4, 6, 7, 9])

print(np.diff(arr1))  # 一维计算差分

print("=" * 100)
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr1)
print(np.diff(arr1, axis=0))  # 纵向九四u按差分
print(np.diff(arr1, axis=1))  # 横向计算差分

# 统计函数
# 最大值，最小值，中位数，平均值，方差，标准差
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
print("=" * 100)
print(np.max(arr1))  # 全局计算最大值
print(np.amax(arr1, axis=0))  # 纵向计算最大值
print(np.amax(arr1, axis=1))  # 横向计算最大值

# 中位数
print(np.median(arr1))
print(np.median(arr1, axis=0))
print(np.median(arr1, axis=1))

# 标准差：用于评估一组数的偏差程度
print(np.std(arr1))
print(np.std(np.array([5, 5, 5, 5, 5000])))

# 均值
print(np.mean(arr1))
print(np.mean(arr1, axis=0))
print(np.mean(arr1, axis=1))

# 生成随机数

print(np.random.rand(4, 4))
print(np.random.rand(4, 4) * 100)
print(np.random.randint(2, 3))  # 生成一个随机数

# 随机生成满足标准正太分布数据
print(np.random.normal(size=(4, 4)))

# 使用后numpy表示数学中的公式
x = np.array([1, 2, 3, 4, 5, 6, 7, 8])

y = 3 * x ** 2 + 2 * x + 100

print(y)
